<?php
/**
 * @author Garry
 *
 *
 */
class Dao extends DomainObject {
	public $oid=0;
	/**
	 * 
	 * Construct the DAO
	 * @param unknown_type $first
	 */
	function __construct( $action = FALSE ) {
		$this->mapper = ObjectMapper::GetInstance();
		$this->anonymous = new DomainObjectCollection();
		$this->property_types = array_merge_recursive(
			$this->property_types,
			array(
	                        'id' => array(
	                                                 'type' => 'INT',
	                                                 'constraint' => 6,
	                                                 'unsigned' => TRUE,
	                                                 'auto_increment' => TRUE
	                                          ),
	                        'oid' => array(
	                                                 'type' => 'INT',
	                                                 'constraint' => 6,
	                                                 'unsigned' => TRUE
	                                          ),
                        'childoids' => array(
                                                 'type' => 'TEXT',
                                                 'null' => TRUE,
                                          )
	                     ,
                        'parentobject' => array(
                                                 'type' => 'VARCHAR',
                                                 'constraint' => 12,
	                     						 'null' => TRUE
                                          )       
	                )
			);
		if( is_bool($action) && $action == TRUE ){
			// get a valid object id 
			$this->oid = $this->mapper->GetID( get_class( $this ) );
			// load each of these properties into the properties array		
			ObjectWatcher::addNew($this);

		}
		elseif( is_object( $action )){
			$this->mapper->LoadProperties( $this,$action );
		}
		elseif( is_numeric( $action )){
			$this->oid = $action;
			$this->mapper->load( $this );
		}
	}

	/**
	 *
	 * @param  unknown_type $object
	 * @see DomainObject::doAddObject()
	 */
	protected  function doAddObject($object) {
		if( ! $object instanceof DomainObject ){
			throw new InvalidArgumentException("Only objects of type domain object may be added to Domain Objects", 102);
		}
		// add in this as the parent
		$object->parentobject = $this;
	    if( !$this->anonymous->contains( $object ) ){
	    	$this->anonymous->addElement( $object );
	    }
		if(is_string($this->childoids) && strlen($this->childoids) > 0 ){
			$this->childoids = explode(",",$this->childoids);
		}
	    $this->childoids[]=  $object->oid;
	    $this->childoids = implode(",",$this->childoids);
		$this->changed['childoids'] = $this->childoids; 
		$this->markChanged();
		//TODO - Insert your code here
	}
	/***
	 * 
	 * actual delete method
	 */
	public function doDelete( ){
		$deletes = array();
		$this->DeletePropertyObject($deletes);
		$ids = array();
		foreach (array_values($deletes) as $id_row){
			foreach($id_row as $id){
				$ids[]=$id;
			}
		}
		$this->mapper->executeDelete(array_keys($deletes),$ids);
	}
	/***
	 * Internal delete assembly
	 */
	protected function DeletePropertyObject(Array &$deletes){
		$this->addDeleteID($deletes,get_class( $this ),$this->oid );
		if($this->propagateDeleteToChildren){
			foreach ($this->properties as $key => $props ){
				if( $props != null && $key != "parentobject" ){
					if(!$props instanceof DomainObject){
				 	$props = $this->__get($key);
					}
					else
					{
					$props->propagateDeleteToChildren = $this->propagateDeleteToChildren;
					$props->DeletePropertyObject($deletes);
					}
				}
			}
			// now handle the anonymous children
			$children = $this->doGetObjects();
			foreach ($children as $child){
				$child->propagateDeleteToChildren = $this->propagateDeleteToChildren;
				$child->DeletePropertyObject( $deletes );
			}			
		}
		return $deletes;
	}
	/***
	 * utility array function
	 */
	protected function addDeleteID(Array &$deletes,$class,$prop){
		if( !array_key_exists($class, $deletes) ){
			$deletes[$class]=array();
		}
		array_push($deletes[$class], $prop);
	}
	/**
	 * load in child objects
	 * @param  unknown_type $object
	 * @see DomainObject::doGetObjects()
	 */
	protected  function doGetObjects() {
		if(is_array($this->childoids)){
			$this->childoids = implode(",",$this->childoids);
		}
		if( count( $this->childoids )>0 && $this->anonymous->size() == 0 ){
			if( strlen($this->childoids) > 0 ){
				$children = $this->mapper->GetByIds( $this->childoids );
				foreach($children as $child){
					$this->anonymous->addElement( $child );
				}
			}
		}
		return $this->anonymous;
		//TODO - Insert your code here
	}
	/**
	 * 
	 * 
	 * Lazy loading of child object
	 * @param unknown_type $oid
	 */
	public function doGetObject( $oid ){
		$object = $this->anonymous->find($oid);
		if( empty($object) ){
			$object = $this->mapper->loadObject( $oid );
		}
		return $object;
	}
	
	/* (non-PHPdoc)
	 * @see DomainObject::remove()
	 */
	public function remove( DomainObject $object=NULL  ){
		if(is_array($this->childoids)){
			$this->childoids = implode(",",$this->childoids);
		}
		$chkArray = explode( ",",$this->childoids );
		if( $object instanceof DomainObject ){
			$oid = $object->oid;
		}
		if( in_array($oid, $chkArray )){
			$remove = array_search( $oid, $chkArray );
			unset($chkArray[$remove]);
			$this->childoids = implode(",", $chkArray );
			$this->changed['childoids'] = $this->childoids; 
			$this->markChanged();
		}
		else {
			return FALSE;
		}
		return $object;
	}
	/**
	 *
	 * @param  unknown_type $type

	 * @see DomainObject::getMapper()
	 */
	protected  function getMapper($type) {

		return $this->mapper;
	}
	/**
	 *
	 * @see DomainObject::setMapper()
	 */
	public  function setMapper() {

		//TODO - Insert your code here
	}
	/***
	 * static functionality
	 */
	public static function ItemExists( $class,$oid ){
		$mapper = ObjectMapper::GetInstance();
		return $mapper->itemExists($class,$oid);
	}
	
	/**
	 * Search the db for a given Dao
	 * @param unknown_type $class
	 * @param unknown_type $terms
	 */
	public static function Search( $class,$terms ){
		$mapper = ObjectMapper::GetInstance();
		return $mapper->search($class,$terms);
	}
}


?>